﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using X.PagedList;
using XbsWebAPI.Application.CheckInOut.Dtos;
using XbsWebAPI.Application.QueryModel;
using XbsWebAPI.Core.Repositories;
using XbsWebAPI.EntityFrameworkCore.Entities.Enums;

namespace XbsWebAPI.Application.OrderFinance
{
    /// <summary>
    /// 订单管理
    /// </summary>
    public class OrderAppService : IOrderAppService
    {
        private readonly IOrderRepository _orderRepository;
        private readonly IRoomRepository _roomRepository;
        private readonly IHouseTypeRepository _houseTypeRepository;
        private readonly ILogger<OrderAppService> _logger;
        private readonly IMapper _mapper;


        public OrderAppService(IOrderRepository orderRepository,IRoomRepository roomRepository,ILogger<OrderAppService> logger, IMapper mapper,IHouseTypeRepository houseTypeRepository)
        { 
            _orderRepository = orderRepository;
            _roomRepository = roomRepository;
            _houseTypeRepository = houseTypeRepository;
            _logger = logger;
            _mapper = mapper;
        }

        public Task<ResultDto<string>> ConfirmOrderDetailAsync(Guid orderId)
        {
            var result = new ResultDto<string>();
            try
            {
                var order = _orderRepository.QueryById(orderId);
                if (order == null)
                {
                    result.Code = -1;
                    result.Message = $"ConfirmOrderDetailAsync:ID={orderId}不存在";
                    _logger.LogError(result.Message);
                    return Task.FromResult(result);
                }
                order.OrderStatus = OrderStatus.Confirmed;
                _orderRepository.UpdateAsync(order);
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                _logger.LogError(result.Message);
                return Task.FromResult(result);
            }
            return Task.FromResult(result);
        }

        public ResultDto<List<SelectHouseTypeDto>> GetAllOrdersHouseTypes()
        {
            var result = new ResultDto<List<SelectHouseTypeDto>>();
            try
            {
                var list = _orderRepository.AsQueryable().Select(a => new { Id = a.HouseTypeId, Name = a.HouseTypeName }).Distinct().ToList();
                var dtos = new List<SelectHouseTypeDto>();
                foreach (var houseType in list)
                {
                    if (dtos.Any(a => a.Id == houseType.Id))
                        continue;

                    dtos.Add(new SelectHouseTypeDto
                    {
                        Id = houseType.Id.Value,
                        Name = houseType.Name
                    });
                }
                result.Message = "操作成功";
                result.Result = dtos;
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                _logger.LogError($"GetAllOrdersHouseTypes:异常：{e.Message}");
                return result;
            }
            return result;
        }

        public ResultDto<OrderDetailDto> GetOrderById(Guid orderId)
        {
            var result = new ResultDto<OrderDetailDto>();
            try
            {
                var order = _orderRepository.QueryById(orderId);
                string errMsg;
                if (order == null)
                {
                    errMsg = $"GetOrderById：ID={orderId}订单不存在";
                    _logger.LogError(errMsg);
                    throw new Exception(errMsg);
                }

                var room = _roomRepository.AsQueryable()
                    .Include(a => a.HouseType)
                    .FirstOrDefault(a => a.Id == order.RoomId);

                if (room == null)
                {
                    errMsg = $"GetOrderById：ID={orderId}的房间不存在";
                    _logger.LogError(errMsg);
                    throw new Exception(errMsg);
                }

                if (room.HouseType == null)
                {
                    errMsg = $"GetOrderById：ID={orderId}的房型不存在";
                    _logger.LogError(errMsg);
                    throw new Exception(errMsg);
                }

                var dto = new OrderDetailDto
                {
                    OrderNumber = order.OrderNumber,
                    OrderTime = order.OrderTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    BookingPerson = order.Guests,
                    PhoneNumber = order.PhoneNumber,
                    PaymentTime = order.PaymentTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    TotalPrice = order.TotalPrice,
                    ActualPayment = order.ActualPayment,
                    HouseTypeName = order.HouseTypeName,
                    CheckInDate = order.CheckInDate.ToString("yyyy-MM-dd"),
                    CheckOutDate = order.CheckOutDate.ToString("yyyy-MM-dd"),
                    WxName = order.WxName,
                    WxPhoneNumber = order.WxPhoneNumber,
                    BreakfastCount = room.HouseType.BreakfastCount,
                    RoomCount = 1
                };

                result.Result = dto;
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                _logger.LogError($"GetOrderById:ID={orderId}异常：{e.Message}");
                result.Message = e.Message;
                result.Code = -1;
                return result;
            }
                

            return result;
        }

        public ResultDto<PageListDto<ListOrderDetailDto>> GetPagedList(QueryOrderDetail query)
        {
            var result = new ResultDto<PageListDto<ListOrderDetailDto>>();

            try
            {
                var orderDetails = _orderRepository.AsQueryable();

                if (query.IsContinueToLive != null)
                {
                    orderDetails = orderDetails.Where(a => a.IsContinueToLive == query.IsContinueToLive);
                }

                if (query.HouseTypeId != null)
                {
                    orderDetails = orderDetails.Where(a => a.HouseTypeId == query.HouseTypeId);
                }

                if (!string.IsNullOrEmpty(query.Data))
                {
                    orderDetails = orderDetails.Where(a => a.Guests.Contains(query.Data) || a.PhoneNumber.Contains(query.Data) || a.OrderNumber.Contains(query.Data));
                }

                if(query.OrderTimeBegin.HasValue || query.OrderTimeEnd.HasValue)
                {
                    //先判断是哪种类型
                    if(query.OrderTimeType == OrderTimeType.Booking)
                    {
                        //如果有时间
                        if(query.OrderTimeBegin.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.PaymentTime >= query.OrderTimeBegin);
                        }
                        if (query.OrderTimeEnd.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.PaymentTime <= query.OrderTimeEnd);
                        }
                    }

                    if (query.OrderTimeType == OrderTimeType.CheckIn)
                    {
                        //如果有时间
                        if (query.OrderTimeBegin.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.CheckInDate >= query.OrderTimeBegin);
                        }
                        if (query.OrderTimeEnd.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.CheckInDate <= query.OrderTimeEnd);
                        }
                    }

                    if (query.OrderTimeType == OrderTimeType.CheckOut)
                    {
                        //如果有时间
                        if (query.OrderTimeBegin.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.CheckOutDate >= query.OrderTimeBegin);
                        }
                        if (query.OrderTimeEnd.HasValue)
                        {
                            orderDetails = orderDetails.Where(a => a.CheckOutDate <= query.OrderTimeEnd);
                        }
                    }
                }

                orderDetails = orderDetails.OrderByDescending(a => a.CreationDate);
                var pagedList = orderDetails.ToPagedList(query.PageNumber ?? 1, query.PageSize ?? 10);
                PageListDto<ListOrderDetailDto> pagedDto = new PageListDto<ListOrderDetailDto>()
                {
                    PageNumber = pagedList.PageNumber,
                    PageSize = pagedList.PageSize,
                    HasPreviousPage = pagedList.HasPreviousPage,
                    HasNextPage = pagedList.HasNextPage,
                    TotalCount = pagedList.TotalItemCount
                };
                var dtos = pagedList.Select(e => _mapper.Map<ListOrderDetailDto>(e)).ToList();

                foreach (var dto in dtos)
                {
                    dto.CheckInDate = Convert.ToDateTime(dto.CheckInDate).ToString("yyyy-MM-dd");
                    dto.CheckOutDate = Convert.ToDateTime(dto.CheckOutDate).ToString("yyyy-MM-dd");
                    if (dto.HouseTypeId != null)
                    {
                        var houseType = _houseTypeRepository.QueryById(dto.HouseTypeId.Value);
                        if (houseType != null)
                        {
                            dto.HouseTypeName = houseType.Name;
                        }
                    }


                }

                pagedDto.Dtos = dtos;

                result.Code = 0;
                result.Message = "操作成功";
                result.Result = pagedDto;
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                result.Result = null;
                return result;
            }

            return result;
        }

        public void InitOrdersFromTest()
        {
            throw new NotImplementedException();
        }
    }
}
